package com.shycloud.mido.homework.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shycloud.mido.common.core.constant.SecurityConstants;
import com.shycloud.mido.homework.api.entity.MidoHomeworkComplateWeek;
import com.shycloud.mido.homework.mapper.MidoHomeworkComplateWeekMapper;
import com.shycloud.mido.homework.service.MidoHomeworkComplateWeekService;
import com.shycloud.mido.member.api.feign.RemoteMemberService;
import com.shycloud.mido.member.api.vo.WeekDataMemberVO;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shycloud.mido.homework.api.entity.MidoHomeworkMain;
import com.shycloud.mido.homework.api.entity.StudentPlayData;
import com.shycloud.mido.homework.api.entity.WeekBestHomework;
import com.shycloud.mido.homework.api.entity.WeekDataMember;
import com.shycloud.mido.homework.api.entity.WeekDataMemberHomeworkType;
import com.shycloud.mido.homework.api.entity.WeekHomeworkTypeDetail;
import com.shycloud.mido.homework.api.entity.WeekMain;
import com.shycloud.mido.homework.api.vo.WeekBestHomeworkVO;
import com.shycloud.mido.homework.api.vo.WeekHomeworkTypeDetailVO;
import com.shycloud.mido.homework.api.vo.WeekPayloadVO;
import com.shycloud.mido.homework.constant.Constant;
import com.shycloud.mido.homework.mapper.MidoHomeworkMainMapper;
import com.shycloud.mido.homework.mapper.MidoHomeworkPlayDataMapper;
import com.shycloud.mido.homework.mapper.WeekBestHomeworkMapper;
import com.shycloud.mido.homework.mapper.WeekDataMemberHomeworkTypeMapper;
import com.shycloud.mido.homework.mapper.WeekHomeworkTypeDetailMapper;
import com.shycloud.mido.homework.mapper.WeekMainMapper;
import com.shycloud.mido.homework.service.MidoHomeworkWeekService;
import com.shycloud.mido.homework.service.WeekBestHomeworkService;
import com.shycloud.mido.homework.service.WeekDataMemberHomeworkTypeService;
import com.shycloud.mido.homework.service.WeekDataMemberService;
import com.shycloud.mido.homework.service.WeekHomeworkTypeDetailService;
import com.shycloud.mido.member.api.entity.MemberActivateEntity;
import com.shycloud.mido.member.api.feign.RemotePushService;
import com.shycloud.mido.member.api.util.UUIDUtil;
import com.shycloud.mido.member.api.vo.WeekMainInMemberFeignVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 周报
 *
 * @author bard.bai
 */
@Slf4j
@Service
@AllArgsConstructor
public class MidoHomeworkWeekServiceImpl implements MidoHomeworkWeekService {

	/** 周报主业务 mapper */
	private final WeekMainMapper weekMainMapper;
	/** 作业完成业务 mapper */
	private final MidoHomeworkComplateWeekMapper midoHomeworkComplateMapper;
	/** 作业完成业务 service */
	private final MidoHomeworkComplateWeekService midoHomeworkComplateService;

	private final MidoHomeworkMainMapper midoHomeworkMainMapper;

	private final MidoHomeworkPlayDataMapper midoHomeworkPlayDataMapper;

	private final WeekDataMemberService weekDataMemberService;

	private final WeekDataMemberHomeworkTypeMapper weekDataMemberHomeworkTypeMapper;

	private final WeekDataMemberHomeworkTypeService weekDataMemberHomeworkTypeService;

	private final WeekHomeworkTypeDetailMapper weekHomeworkTypeDetailMapper;

	private final WeekHomeworkTypeDetailService weekHomeworkTypeDetailService;

	private final WeekBestHomeworkMapper weekBestHomeworkMapper;

	private final WeekBestHomeworkService weekBestHomeworkService;

	private final RemotePushService pushService;
	/***/
	private final RemoteMemberService remoteMemberService;

	/**
	 * 构建周报
	 *
	 * @param payload
	 * @return void
	 * @author bard.bai
	 * @date 2021/8/11 9:01
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void buildWeekMain(WeekPayloadVO payload) {

		log.info("buildWeekMain 开始创建");
		//计时器,记录程序执行的时间
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();

		//<================================== 执行程序 START ==============================>
		LocalDateTime now = payload.getNow();
		WeekMain weekMain = new WeekMain();
		weekMain.setYear(now.getYear());
		LocalDate lastWeekDate = now.toLocalDate();
		// 上周日至这周六 [如果是周日：上周天+6天的范围，如果不是周日 获取前一个周日-7 +6天范围]
		LocalDate preSunday = lastWeekDate.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY));
		if (DayOfWeek.SUNDAY != now.getDayOfWeek()) {
			preSunday = preSunday.minusDays(7);
		}
		LocalDate nowSaturday = preSunday.plusDays(6);
		weekMain.setStartWeekDate(preSunday);
		weekMain.setEndWeekDate(nowSaturday);
		LocalDate startWeekDate = weekMain.getStartWeekDate();
		LocalDate endWeekDate = weekMain.getEndWeekDate();
		LocalDateTime startTime = startWeekDate.atTime(0, 0, 0, 0);
		LocalDateTime endTime = endWeekDate.atTime(23, 59, 59);
		log.info("weekJobBuild周报范围: {} 到 {} ", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(startTime),
				DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(endTime));
		payload.setStartTime(startTime);
		payload.setEndTime(endTime);

		//开始和结束 存在就查询出来
		LambdaQueryWrapper<WeekMain> queryCheckQW = Wrappers.<WeekMain>lambdaQuery()
				.eq(WeekMain::getStartWeekDate, weekMain.getStartWeekDate())
				.eq(WeekMain::getEndWeekDate, weekMain.getEndWeekDate())
				.last("limit 1");
		WeekMain checkWeekMain = weekMainMapper.selectOne(queryCheckQW);
		if (Objects.isNull(checkWeekMain)) {
			//一年第几周
			WeekFields weekFields = WeekFields.of(DayOfWeek.SUNDAY, 1);
			int weeks = lastWeekDate.get(weekFields.weekOfYear());
			weekMain.setWeek(weeks);
			//一个月第几周
			int weekdays = lastWeekDate.get(weekFields.weekOfMonth());
			weekMain.setWeekdays(weekdays);
			//上周周报
			LambdaQueryWrapper<WeekMain> queryQW = Wrappers.<WeekMain>lambdaQuery()
					.eq(WeekMain::getDelFlag, Constant.DEL_FLAG)
					.orderByDesc(WeekMain::getCreateTime).last("limit 1");
			WeekMain preWeekMain = weekMainMapper.selectOne(queryQW);
			String preWeekId = Optional.ofNullable(preWeekMain).map(WeekMain::getId).orElse("0");
			//状态-未计算
			weekMain.setStatus(Constant.WEEK_MAIN_STATUS_UNCALC);
			//上周周报ID
			weekMain.setPreWeekId(preWeekId);
			weekMain.setDelFlag(Constant.DEL_FLAG);
			weekMain.setCreateTime(now);
			weekMain.setUpdateTime(now);
			weekMain.setStep(Constant.WEEK_MAIN_STEP_START);
			weekMainMapper.insert(weekMain);
			payload.setWeekMainId(weekMain.getId());
			payload.setWeekMain(weekMain);

		} else {
			log.info("buildWeekMain 周报已经存在");
			payload.setWeekMainId(checkWeekMain.getId());
			payload.setWeekMain(checkWeekMain);
		}
		log.info("buildWeekMain 执行完成");
		//<================================== 执行程序 E-N-D ==============================>
		stopWatch.stop();
		log.info("buildWeekMain耗时：{}", (double) stopWatch.getTime() / 1000 + "s");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void resolveHomeworkData(WeekPayloadVO payload) {
		log.info("resolveHomeworkData 开始");
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		WeekMain weekMain = payload.getWeekMain();
		if (Constant.WEEK_MAIN_STEP_RESOLVE <= weekMain.getStep()) {
			log.info("resolveHomeworkData 已经解析过 无需再次解析");
			return;
		}
		LocalDateTime startTime = payload.getStartTime();
		LocalDateTime endTime = payload.getEndTime();
		log.info("resolveHomeworkData 分批解析");

		int count = 0;
		LambdaQueryWrapper<MidoHomeworkComplateWeek> queryHomeworkQW = Wrappers.<MidoHomeworkComplateWeek>lambdaQuery()
				.between(MidoHomeworkComplateWeek::getCreateTime, startTime, endTime)
				.isNull(MidoHomeworkComplateWeek::getResolveFlag)
				.or(wrapper1 -> wrapper1.ne(MidoHomeworkComplateWeek::getResolveFlag, "1")
						.ne(MidoHomeworkComplateWeek::getResolveFlag, "2"))
				.orderByAsc(MidoHomeworkComplateWeek::getCreateTime)
				.last("limit " + Constant.BATCH_SIZE);
		List<MidoHomeworkComplateWeek> midoHomeworkComplateList = midoHomeworkComplateMapper.selectList(queryHomeworkQW);
		while (count <= 1_000_000 && CollectionUtils.isNotEmpty(midoHomeworkComplateList)) {
			count++;
			for (MidoHomeworkComplateWeek midoHomeworkComplate : midoHomeworkComplateList) {
				try {
					//TODO 入库数据存在BUG 多条只取一条
					LambdaQueryWrapper<StudentPlayData> studentPlayDataQW = Wrappers.<StudentPlayData>lambdaQuery()
							.eq(StudentPlayData::getHomeworkId, midoHomeworkComplate.getHomeworkId())
							.eq(StudentPlayData::getComplateId, midoHomeworkComplate.getId()).last("limit 1");
					StudentPlayData playData = midoHomeworkPlayDataMapper.selectOne(studentPlayDataQW);
					if (Objects.nonNull(playData)) {
						//解析练琴数据 - 主要解析左右手 音准/节奏错误
						this.resolvePlayData(midoHomeworkComplate, playData);
						if (StringUtils.isBlank(midoHomeworkComplate.getPractiveLength())) {
							//解析练琴时长
							this.resolvePractiveLength(midoHomeworkComplate, playData);
						}
					}
					//解析完成
					midoHomeworkComplate.setResolveFlag("1");
				} catch (Exception e) {
					e.printStackTrace();
					log.error(e.getMessage(), e);
					//解析失败
					midoHomeworkComplate.setResolveFlag("2");
				}
			}
			if (CollectionUtils.isNotEmpty(midoHomeworkComplateList)) {
				midoHomeworkComplateService.saveOrUpdateBatch(midoHomeworkComplateList);
			}
			//下次循环
			queryHomeworkQW = Wrappers.<MidoHomeworkComplateWeek>lambdaQuery()
					.between(MidoHomeworkComplateWeek::getCreateTime, startTime, endTime)
					.isNull(MidoHomeworkComplateWeek::getResolveFlag)
					.or(wrapper1 -> wrapper1.ne(MidoHomeworkComplateWeek::getResolveFlag, "1")
							.ne(MidoHomeworkComplateWeek::getResolveFlag, "2"))
					.last("limit " + Constant.BATCH_SIZE);
			midoHomeworkComplateList = midoHomeworkComplateMapper.selectList(queryHomeworkQW);
		}

		//更新步骤
		LambdaUpdateWrapper<WeekMain> weekMailUW = Wrappers.<WeekMain>lambdaUpdate()
				.set(WeekMain::getStep, Constant.WEEK_MAIN_STEP_RESOLVE)
				.eq(WeekMain::getId, payload.getWeekMainId());
		weekMainMapper.update(null, weekMailUW);
		payload.getWeekMain().setStep(Constant.WEEK_MAIN_STEP_RESOLVE);
		log.info("resolveHomeworkData 完成");
		stopWatch.stop();
		log.info("resolveHomeworkData 耗时：{}", (double) stopWatch.getTime() / 1000 + "s");

	}

	/**
	 * 计算左右手数据
	 *
	 * @param midoHomeworkComplate
	 * @param playData
	 * @return void
	 * @author nianhua.jiang
	 * @date 2021/8/11 13:44
	 */
	public void resolvePlayData(MidoHomeworkComplateWeek midoHomeworkComplate, StudentPlayData playData) {

		//定义左手音准错误数量
		int leftHandIntonationError = 0;
		//定义左手节奏错误数量
		int leftHandRhythmError = 0;
		//定义右手音准错误数量
		int rightHandIntonationError = 0;
		//定义右手节奏错误数量
		int rightHandRhythmError = 0;

		//开始解析 json =====================>
		JSONObject jsonObject = JSON.parseObject(playData.getPlayData());
		JSONArray dotsArray = jsonObject.getJSONArray("dots");
		if (Objects.nonNull(dotsArray)) {
			for (int i = 0; i < dotsArray.size(); i++) {
				JSONObject dot = dotsArray.getJSONObject(i);
				// 分数
				Integer score = dot.getInteger("score");
				if (Objects.nonNull(score)) {
					JSONObject nObject = dot.getJSONObject("n");
					// 左右手
					Boolean hand = nObject.getBoolean("hand");
					if (hand) {
						// true 右手
						if (0 == score) {
							// 0 音准错
							rightHandIntonationError++;
						} else if (1 == score) {
							// 1 节奏错
							rightHandRhythmError++;
						}
					} else {
						// false 左手
						if (0 == score) {
							// 0 音准错
							leftHandIntonationError++;
						} else if (1 == score) {
							// 1 节奏错
							leftHandRhythmError++;
						}
					}
				}
			}
		}
		//解析 json 结束 =====================>

		//左手音准错误
		midoHomeworkComplate.setLeftHandIntonation(leftHandIntonationError);
		//左手节奏错误
		midoHomeworkComplate.setLeftHandRhythm(leftHandRhythmError);
		//右手音准错误
		midoHomeworkComplate.setRightHandIntonation(rightHandIntonationError);
		//右手节奏错误
		midoHomeworkComplate.setRightHandRhythm(rightHandRhythmError);

	}

	/**
	 * 解析练琴时长
	 *
	 * @param midoHomeworkComplate
	 * @param playData
	 * @return
	 * @author nianhua.jiang
	 * @date 2021/8/11 9:08
	 */
	public void resolvePractiveLength(MidoHomeworkComplateWeek midoHomeworkComplate, StudentPlayData playData) {

		//获取作业信息
		MidoHomeworkMain midoHomeworkMain = midoHomeworkMainMapper.selectById(midoHomeworkComplate.getHomeworkId());
		//纠错模式并且全部完成时,开始解析
		if (Objects.nonNull(midoHomeworkMain)
				&& StringUtils.equals("2", midoHomeworkMain.getPlayingMode())
				&& StringUtils.equals("2", midoHomeworkMain.getStatus())) {

			JSONObject jsonObject = JSON.parseObject(playData.getPlayData());
			//练琴时长 json 段
			JSONArray dotsArray = jsonObject.getJSONArray("cursors");
			if (Objects.nonNull(dotsArray)) {
				int size = dotsArray.size();
				if (size >= 1) {
					JSONObject cursorStart = dotsArray.getJSONObject(0);
					JSONObject cursorEnd = dotsArray.getJSONObject(size - 1);
					//毫秒
					Integer practive = cursorEnd.getInteger("time") - cursorStart.getInteger("time");
					//秒
					practive = (int) Math.ceil(practive / 1000);
					LambdaUpdateWrapper<MidoHomeworkComplateWeek> update = Wrappers.<MidoHomeworkComplateWeek>lambdaUpdate()
							.set(MidoHomeworkComplateWeek::getPractiveLength, practive)
							.eq(MidoHomeworkComplateWeek::getId, midoHomeworkComplate.getId());
					midoHomeworkComplateMapper.update(null, update);
				}
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void generateWeekMember(WeekPayloadVO payload) {
		log.info("generateWeekMember 开始");
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		WeekMain weekMain = payload.getWeekMain();
		if (Constant.WEEK_MAIN_STEP_MEMBER <= weekMain.getStep()) {
			log.info("generateWeekMember 已经解析过 无需再次解析");
			return;
		}
		LocalDateTime startTime = payload.getStartTime();
		LocalDateTime endTime = payload.getEndTime();
		//删除旧数据
		LambdaQueryWrapper<WeekDataMember> weekDataMemberRM = Wrappers.<WeekDataMember>lambdaQuery()
				.eq(WeekDataMember::getWeekId, payload.getWeekMainId());
		weekDataMemberService.remove(weekDataMemberRM);

		LambdaQueryWrapper<WeekDataMemberHomeworkType> weekDataMemberHomeworkTypeRM = Wrappers.<WeekDataMemberHomeworkType>lambdaQuery()
				.eq(WeekDataMemberHomeworkType::getWeekId, payload.getWeekMainId());
		weekDataMemberHomeworkTypeService.remove(weekDataMemberHomeworkTypeRM);

		LambdaQueryWrapper<WeekHomeworkTypeDetail> weekHomeworkTypeDetailRM = Wrappers.<WeekHomeworkTypeDetail>lambdaQuery()
				.eq(WeekHomeworkTypeDetail::getWeekId, payload.getWeekMainId());
		weekHomeworkTypeDetailService.remove(weekHomeworkTypeDetailRM);

		LambdaQueryWrapper<WeekBestHomework> weekBestHomeworkRM = Wrappers.<WeekBestHomework>lambdaQuery()
				.eq(WeekBestHomework::getWeekId, payload.getWeekMainId());
		weekBestHomeworkService.remove(weekBestHomeworkRM);

		log.info("generateWeekMember 分页遍历");

		int index = 1;
		int count = 0;

		List<WeekDataMemberVO> records = remoteMemberService
				.pageMemberListByWeekV3(index, Constant.BATCH_SIZE, SecurityConstants.FROM_IN);

		List<WeekDataMember> resWeekDataMembers = new ArrayList<>();
		//WeekDataMemberHomeworkType
		List<WeekDataMemberHomeworkType> weekDataMemberHomeworkTypeList = new ArrayList<WeekDataMemberHomeworkType>();
		//WeekHomeworkTypeDetail
		List<WeekHomeworkTypeDetail> weekHomeworkTypeDetailList = new ArrayList<WeekHomeworkTypeDetail>();
		//WeekBestHomework
		List<WeekBestHomework> weekBestHomeworkList = new ArrayList<WeekBestHomework>();
		while (count <= 1_000_000 && CollectionUtils.isNotEmpty(records)) {
			count++;
			for (WeekDataMemberVO weekMember : records) {
				try {
					weekMember.setId(UUIDUtil.getUUID32());
					weekMember.setWeekId(weekMain.getId());
					weekMember.setPreWeekId(weekMain.getPreWeekId());
					weekMember.setDelFlag(Constant.DEL_FLAG);
					weekMember.setCreateTime(LocalDateTime.now());
					weekMember.setUpdateTime(LocalDateTime.now());
					weekMember.setPushFlag(Constant.WEEK_PUSH_FLAG_UNABLE);
					//计算是否可以推送周报条件
					MemberActivateEntity activate = weekDataMemberService.getMidoMasterByMemberAndWeek(weekMember.getMemberId());

					if (Objects.nonNull(activate)) {
						LocalDateTime startLDT = activate.getStartTime();
						Integer duration = activate.getDuration();
						LocalDateTime endLDT = startLDT.plusDays(duration);
						if (endTime.isBefore(endLDT)) {
							//存在硬件设备激活 //订阅 并且填写生日 琴龄 目标 信息
							if (StringUtils.isNoneBlank(weekMember.getBirthday(),
									weekMember.getPlayYears(), weekMember.getPlayTarget())
									&& StringUtils.equals("0", weekMember.getSubscribe())) {
								//待推送
								weekMember.setPushFlag(Constant.WEEK_PUSH_FLAG_WAIT);
							}
						}
					}

					//计算周数据
					if (StringUtils.isNotBlank(weekMember.getBirthday())) {
						LocalDate birthdayLD = LocalDate
								.from(DateTimeFormatter.ofPattern("yyyy-MM-dd").parse(weekMember.getBirthday()));
						long age = ChronoUnit.YEARS.between(birthdayLD, weekMain.getEndWeekDate());
						//年龄
						weekMember.setAge(Integer.valueOf(String.valueOf(age)));
					}
					//识谱 时长
					WeekDataMemberHomeworkType weekDataMemberHomeworkTypeParam1 = new WeekDataMemberHomeworkType();
					weekDataMemberHomeworkTypeParam1.setDataWeekId(weekMember.getId());
					weekDataMemberHomeworkTypeParam1.setMemberId(weekMember.getMemberId());
					weekDataMemberHomeworkTypeParam1.setStudentId(weekMember.getStudentId());
					weekDataMemberHomeworkTypeParam1.setType("1");
					WeekDataMemberHomeworkType dataMemberHomeworkType1 = weekDataMemberHomeworkTypeMapper
							.getDataMemberHomeworkType(weekDataMemberHomeworkTypeParam1, payload);
					if (Objects.isNull(dataMemberHomeworkType1)) {
						dataMemberHomeworkType1 = new WeekDataMemberHomeworkType();
					}
					//纠错 时长
					WeekDataMemberHomeworkType weekDataMemberHomeworkTypeParam2 = new WeekDataMemberHomeworkType();
					weekDataMemberHomeworkTypeParam2.setDataWeekId(weekMember.getId());
					weekDataMemberHomeworkTypeParam2.setMemberId(weekMember.getMemberId());
					weekDataMemberHomeworkTypeParam2.setStudentId(weekMember.getStudentId());
					weekDataMemberHomeworkTypeParam2.setType("2");
					WeekDataMemberHomeworkType dataMemberHomeworkType2 = weekDataMemberHomeworkTypeMapper
							.getDataMemberHomeworkType(weekDataMemberHomeworkTypeParam2, payload);
					if (Objects.isNull(dataMemberHomeworkType2)) {
						dataMemberHomeworkType2 = new WeekDataMemberHomeworkType();
					}
					//总练琴时长
					weekMember.setPractiveLength(
							dataMemberHomeworkType1.getPractiveLength() + dataMemberHomeworkType2.getPractiveLength());

					//识谱 count done完成 1-识谱,2-纠错 作业 weekMember 练琴时长 只有存在练琴 才能获取解析
					Integer count1 = weekDataMemberHomeworkTypeMapper
							.getDataMemberHomeworkTypeCount2(weekMember.getStudentId(), payload, "1");
					Integer count2 = weekDataMemberHomeworkTypeMapper
							.getDataMemberHomeworkTypeCount2(weekMember.getStudentId(), payload, "2");

					Integer countDone1 = weekDataMemberHomeworkTypeMapper
							.getDataMemberHomeworkTypeCountDone(weekMember.getStudentId(), payload);
					Integer countDone2 = weekDataMemberHomeworkTypeMapper
							.getDataMemberHomeworkTypeCountDone2(weekMember.getStudentId(), payload);

					//构建入库数据
					dataMemberHomeworkType1.setId(UUIDUtil.getUUID32());
					dataMemberHomeworkType2.setId(UUIDUtil.getUUID32());
					dataMemberHomeworkType1.setWeekId(payload.getWeekMainId());
					dataMemberHomeworkType2.setWeekId(payload.getWeekMainId());
					dataMemberHomeworkType1.setDataWeekId(weekMember.getId());
					dataMemberHomeworkType2.setDataWeekId(weekMember.getId());
					dataMemberHomeworkType1.setCreateTime(LocalDateTime.now());
					dataMemberHomeworkType2.setCreateTime(LocalDateTime.now());
					dataMemberHomeworkType1.setHomeworkCount(count1);
					dataMemberHomeworkType2.setHomeworkCount(count2);
					dataMemberHomeworkType1.setHomeworkDoneCount(countDone1);
					dataMemberHomeworkType2.setHomeworkDoneCount(countDone2);
					dataMemberHomeworkType1.setMemberId(weekMember.getMemberId());
					dataMemberHomeworkType2.setMemberId(weekMember.getMemberId());
					weekDataMemberHomeworkTypeList.add(dataMemberHomeworkType1);
					weekDataMemberHomeworkTypeList.add(dataMemberHomeworkType2);

					//识谱作业数据:例 - 下发5次【爷爷的大钟】完成1次，未完成4次
					/*
						-----------------------------------------------------------------------------------------------
					    |group_id            | music_id |  music_name  | homework_done_count |   homework_undone_count |
					    -----------------------------------------------------------------------------------------------
					    |2529044881956638720 |	10874	|  003爷爷的大钟 |	      1	         |         4               |
					 	-----------------------------------------------------------------------------------------------
					 */
					List<WeekHomeworkTypeDetailVO> weekHomeworkTypeDetailData1 = weekHomeworkTypeDetailMapper
							.getWeekHomeworkTypeDetailData(weekMember.getStudentId(), payload, "1");

					List<WeekHomeworkTypeDetailVO> weekHomeworkTypeDetailData2 = weekHomeworkTypeDetailMapper
							.getWeekHomeworkTypeDetailData(weekMember.getStudentId(), payload, "2");

					//构建【识谱作业】未完成作业数据 （应该将这四条未完成的作业插进 week_homework_type_detail 表 ）
					if (CollectionUtils.isNotEmpty(weekHomeworkTypeDetailData1)) {
						for (WeekHomeworkTypeDetailVO weekHomeworkTypeDetailVO : weekHomeworkTypeDetailData1) {
							// 记录未完成作业的信息
							WeekHomeworkTypeDetail weekHomeworkTypeDetail1 = new WeekHomeworkTypeDetail();
							BeanUtils.copyProperties(weekHomeworkTypeDetailVO, weekHomeworkTypeDetail1);
							weekHomeworkTypeDetail1.setCreateTime(LocalDateTime.now());
							weekHomeworkTypeDetail1.setMemberId(weekMember.getMemberId());
							weekHomeworkTypeDetail1.setStudentId(weekMember.getStudentId());
							weekHomeworkTypeDetail1.setWeekId(payload.getWeekMainId());
							weekHomeworkTypeDetail1.setType("1");
							weekHomeworkTypeDetail1.setWeekHomeworkTypeId(dataMemberHomeworkType1.getId());

							//查询练琴数据
							WeekHomeworkTypeDetailVO weekPractiveTypeDetailData = weekHomeworkTypeDetailMapper
									.getWeekPractiveTypeDetailData(weekHomeworkTypeDetailVO.getHomeworkId(),
											weekMember.getStudentId(), null);

							if (Objects.nonNull(weekPractiveTypeDetailData)) {
								weekHomeworkTypeDetail1.setBestLength(weekPractiveTypeDetailData.getBestLength());
								weekHomeworkTypeDetail1.setMusicLength(weekPractiveTypeDetailData.getMusicLength());
								weekHomeworkTypeDetail1.setPractiveTimes(weekPractiveTypeDetailData.getPractiveTimes());
								weekHomeworkTypeDetail1.setPractiveLength(weekPractiveTypeDetailData.getPractiveLength());
							}
							weekHomeworkTypeDetailList.add(weekHomeworkTypeDetail1);
						}
					}

					if (CollectionUtils.isNotEmpty(weekHomeworkTypeDetailData2)) {
						for (WeekHomeworkTypeDetailVO weekHomeworkTypeDetailVO : weekHomeworkTypeDetailData2) {
							WeekHomeworkTypeDetail weekHomeworkTypeDetail2 = new WeekHomeworkTypeDetail();
							BeanUtils.copyProperties(weekHomeworkTypeDetailVO, weekHomeworkTypeDetail2);
							weekHomeworkTypeDetail2.setCreateTime(LocalDateTime.now());
							weekHomeworkTypeDetail2.setMemberId(weekMember.getMemberId());
							weekHomeworkTypeDetail2.setStudentId(weekMember.getStudentId());
							weekHomeworkTypeDetail2.setWeekId(payload.getWeekMainId());
							weekHomeworkTypeDetail2.setType("2");
							weekHomeworkTypeDetail2.setWeekHomeworkTypeId(dataMemberHomeworkType2.getId());
							//查询练琴数据
							WeekHomeworkTypeDetailVO weekPractiveTypeDetailData = weekHomeworkTypeDetailMapper
									.getWeekPractiveTypeDetailData(weekHomeworkTypeDetailVO.getHomeworkId(),
											weekMember.getStudentId(), null);
							if (Objects.nonNull(weekPractiveTypeDetailData)) {
								weekHomeworkTypeDetail2.setBestLength(weekPractiveTypeDetailData.getBestLength());
								weekHomeworkTypeDetail2.setMusicLength(weekPractiveTypeDetailData.getMusicLength());
								weekHomeworkTypeDetail2.setPractiveTimes(weekPractiveTypeDetailData.getPractiveTimes());
								weekHomeworkTypeDetail2.setPractiveLength(weekPractiveTypeDetailData.getPractiveLength());
							}
							weekHomeworkTypeDetailList.add(weekHomeworkTypeDetail2);
						}
					}

					//作业总数和完成数
					BigDecimal countBD = new BigDecimal(count1 + count2);
					BigDecimal countDoneBD = new BigDecimal(countDone1 + countDone2);
					weekMember.setHomeworkCount(count1 + count2);
					weekMember.setHomeworkDoneCount(countDone1 + countDone2);
					//练琴次数
					weekMember
							.setPractiveTimes(dataMemberHomeworkType1.getPractiveTimes() + dataMemberHomeworkType2.getPractiveTimes());
					if (0 != countBD.intValue()) {
						BigDecimal homeworkRateBD = countDoneBD.multiply(new BigDecimal(100)).divide(countBD, 2, RoundingMode.HALF_UP);
						//完成率
						weekMember.setHomeworkRate(homeworkRateBD);
					} else {
						weekMember.setHomeworkRate(new BigDecimal(0));
					}
					//高光时刻 TOP3
					List<WeekBestHomeworkVO> weekBestHomeworkByStudent = weekBestHomeworkMapper
							.getWeekBestHomeworkByStudent(weekMember.getStudentId(), payload);
					if (CollectionUtils.isNotEmpty(weekBestHomeworkByStudent)) {
						for (WeekBestHomeworkVO weekBestHomeworkVO : weekBestHomeworkByStudent) {
							WeekBestHomework weekBestHomework = new WeekBestHomework();
							BeanUtils.copyProperties(weekBestHomeworkVO, weekBestHomework);
							weekBestHomework.setWeekId(payload.getWeekMainId());
							weekBestHomework.setWeekHomeworkTypeId(dataMemberHomeworkType2.getId());
							weekBestHomework.setMemberId(weekMember.getMemberId());
							weekBestHomework.setStudentId(weekMember.getStudentId());
							weekBestHomework.setType("2");
							weekBestHomeworkList.add(weekBestHomework);
						}
					}
					//计算完成
					weekMember.setStatus("2");

					WeekDataMember weekDataMember = new WeekDataMember();

					BeanUtils.copyProperties(weekMember, weekDataMember);

					resWeekDataMembers.add(weekDataMember);

				} catch (Exception e) {
					e.printStackTrace();
					log.error(e.getMessage(), e);
					//计算失败
					weekMember.setStatus("3");
				}
			}
			if (CollectionUtils.isNotEmpty(weekDataMemberHomeworkTypeList)) {
				weekDataMemberHomeworkTypeService.saveOrUpdateBatch(weekDataMemberHomeworkTypeList);
			}
			if (CollectionUtils.isNotEmpty(weekHomeworkTypeDetailList)) {
				weekHomeworkTypeDetailService.saveOrUpdateBatch(weekHomeworkTypeDetailList);
			}
			if (CollectionUtils.isNotEmpty(weekBestHomeworkList)) {
				weekBestHomeworkService.saveOrUpdateBatch(weekBestHomeworkList);
			}
			//入库
			weekDataMemberService.saveOrUpdateBatch(resWeekDataMembers);

			records = remoteMemberService.pageMemberListByWeekV3(++index, Constant.BATCH_SIZE, SecurityConstants.FROM_IN);

		}
		//更新步骤
		LambdaUpdateWrapper<WeekMain> weekMailUW = Wrappers.<WeekMain>lambdaUpdate()
				.set(WeekMain::getStep, Constant.WEEK_MAIN_STEP_MEMBER)
				.eq(WeekMain::getId, payload.getWeekMainId());
		weekMainMapper.update(null, weekMailUW);
		payload.getWeekMain().setStep(Constant.WEEK_MAIN_STEP_MEMBER);
		log.info("generateWeekMember 完成");
		stopWatch.stop();
		log.info("generateWeekMember耗时：{}", (double) stopWatch.getTime() / 1000 + "s");
	}

	@Override
	public void weekSendMember(WeekPayloadVO payload) {
		log.info("weekSendMember 开始");
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		WeekMain weekMain = payload.getWeekMain();
		if (Constant.WEEK_MAIN_STEP_SEND <= weekMain.getStep()) {
			log.info("weekSendMember 已经解析过 无需再次解析");
			return;
		}
		log.info("weekSendMember 分批解析");
		//调用FEIGN
		WeekMainInMemberFeignVO weekMainInMemberFeignVO = new WeekMainInMemberFeignVO();
		BeanUtils.copyProperties(weekMain, weekMainInMemberFeignVO);
		pushService.sendWeekMsg(weekMainInMemberFeignVO, SecurityConstants.FROM_IN);
		//更新步骤
		LambdaUpdateWrapper<WeekMain> weekMailUW = Wrappers.<WeekMain>lambdaUpdate()
				.set(WeekMain::getStep, Constant.WEEK_MAIN_STEP_SEND)
				.eq(WeekMain::getId, payload.getWeekMainId());
		weekMainMapper.update(null, weekMailUW);
		payload.getWeekMain().setStep(Constant.WEEK_MAIN_STEP_SEND);
		log.info("weekSendMember 完成");
		stopWatch.stop();
		log.info("weekSendMember耗时：{}", (double) stopWatch.getTime() / 1000 + "s");

	}


}
